var $promiseErr = minErr('promise');

/* complete can be used for only one time;
 * whatever,wait can use in any place;
 * then is what waiting complete or wait function finish and then
 * exec;
 * err handle the possible exception which may be casted by complete or wait;
 */
function promise() {
    var that = this;
    p = function() {

    };
    that._callback = [];
    that.isComplete = false;
    that.err = undefined;
    that.errfunc = undefined;
    p.prototype = {
        then: function(func) {
            if (that.err === undefined) {
                if (that.isComplete && that._callback.length === 0) {
                    try {
                        that.result = func(that.result);
                    } catch (e) {
                        that._callback = [];
                        if (that.errfunc !== undefined) {
                            that.errfunc(e);
                        } else {
                            that.err = e;
                        }
                    }
                } else {
                    that._callback.push(func);
                }
            }
            return this;
        },
        wait: function(fv, time) {
            var p = promise();
            setTimeout(function() {
                p.complete(fv);
            }, time);
            while (that._callback.length !== 0) {
                p.then(that._callback.shift());
            }
            p.error(that.errfunc);
            return p;
        },
        complete: function(fv) {
            try {
                if (typeof fv === 'function') {
                    that.result = fv();
                } else {
                    that.result = fv;
                }
            } catch (e) {
                that.result = e;
                that.err = true;
            }

            that.isComplete = true;
            while (that._callback.length > 0) {
                that.result = that._callback.shift()(that.result);
            }
            return this;
        },
        error: function(func) {
            if (that.err) {
                try {
                    func(that.err);
                } catch (e) {
                    $promiseErr('the error method should not cast exception {1}', e);
                }
            } else {
                that.errfunc = func;
            }

        }
    };
    return new p();
}